package cn.kdlc.demo.recycler.adapter;

import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import cn.kdlc.demo.recycler.R;
import cn.kdlc.demo.recycler.model.Header;
import cn.kdlc.demo.recycler.model.User;
import cn.kdlc.demo.recycler.utils.ViewUtils;

import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter;
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange;

import java.util.List;

/**
 * Created by android on 2015/11/26 0026.
 */
public class UserAdapter extends RecyclerView.Adapter<UserHolder> implements DraggableItemAdapter<UserHolder> {

    public static final int VIEW_TYPE_HEADER = 0;

    public static final int VIEW_TYPE_ITEM = 1;

    private List<Header> headers;

    private SparseArray<List<User>> items;

    private int[] headerIndexes;

    private int totalSize = 0;

    public UserAdapter(List<Header> headers, SparseArray<List<User>> items) {
        if (items == null || headers == null) {
            throw new RuntimeException("items cannot be null");
        }

        if (headers.size() != items.size()) {
            throw new RuntimeException("headers' and items' size do not match ");
        }

        this.items = items;
        this.headers = headers;
        int headerSize = items.size();
        headerIndexes = new int[headerSize];
        int itemSize = 0;
        for (int i = 0; i < items.size(); i++) {
            List<User> users = items.valueAt(i);
            if (users != null) {
                headerIndexes[i] = itemSize + i;
                itemSize += users.size();
            }
        }
        totalSize = headerSize + itemSize;
        setHasStableIds(true);
    }

    @Override
    public UserHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = null;
        switch (viewType) {
            case VIEW_TYPE_HEADER:
                itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_header, parent, false);
                break;
            case VIEW_TYPE_ITEM:
                itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
                break;
            default:
                throw new RuntimeException("no such view type");
        }
        UserHolder holder = new UserHolder(itemView, viewType);
        return holder;
    }

    @Override
    public void onBindViewHolder(UserHolder holder, int position) {
        int viewType = holder.getItemViewType();
        int groupPosition = getGroupPosition(position);
        int childPosition = getChildPosition(groupPosition, position);
        switch (viewType) {
            case VIEW_TYPE_HEADER:
                Header header = headers.get(groupPosition);
                holder.bind(header);
                break;
            case VIEW_TYPE_ITEM:
                if (childPosition != -1) {
                    User user = items.get(groupPosition).get(childPosition);
                    holder.bind(user);
                }
                break;
            default:
                throw new RuntimeException("");
        }
    }

    @Override
    public int getItemCount() {
        return totalSize;
    }

    /**
     * 获取组位置
     *
     * @param position
     * @return
     */
    private int getGroupPosition(int position) {
        for (int i = 0; i < headerIndexes.length; i++) {
            if (i < headerIndexes.length - 1) {
                if (position < headerIndexes[i + 1]) {
                    return i;
                } else {
                    continue;
                }
            } else {
                return headerIndexes.length - 1;
            }
        }
        return 0;
    }

    /**
     * 获取
     *
     * @param groupPosition
     * @param position
     * @return
     */
    private int getChildPosition(int groupPosition, int position) {
        return position - headerIndexes[groupPosition] - 1;
    }

    @Override
    public long getItemId(int position) {
        int groupPosition = getGroupPosition(position);
        int childPosition = getChildPosition(groupPosition, position);
        if (childPosition == -1) {
            //标题栏
            return headers.get(groupPosition).getId();
        } else {
            return items.get(groupPosition).get(childPosition).getId();
        }
    }

    @Override
    public int getItemViewType(int position) {
        int groupPosition = getGroupPosition(position);
        int childPosition = getChildPosition(groupPosition, position);
        if (childPosition == -1) {
            //标题栏
            return VIEW_TYPE_HEADER;
        } else {
            return VIEW_TYPE_ITEM;
        }
    }

    @Override
    public boolean onCheckCanStartDrag(UserHolder holder, int position, int x, int y) {
        int viewType = holder.getItemViewType();
        if (viewType == VIEW_TYPE_ITEM) {
            View container = holder.container;
            View dragHandler = holder.dragHandler;
            int offsetX = container.getLeft() + (int) (ViewCompat.getTranslationX(container) + 0.5f);
            int offsetY = container.getTop() + (int) (ViewCompat.getTranslationY(container) + 0.5f);
            return ViewUtils.hitTest(dragHandler, x - offsetX, y - offsetY);
        }
        return false;
    }

    @Override
    public void onMoveItem(int fromPosition, int toPosition) {
        if (fromPosition == toPosition) {
            return;
        }

        int fromGPos = getGroupPosition(fromPosition);
        int fromCPos = getChildPosition(fromGPos, fromPosition);

        int toGPos = getGroupPosition(toPosition);
        int toCPos = getChildPosition(toGPos, toPosition);

        if (fromGPos != toGPos) {
            return;
        }

        if (toCPos == -1) {
            return;
        }

        List<User> users = items.get(fromGPos);
        User user = users.remove(fromCPos);
        users.add(toCPos, user);
        notifyItemMoved(fromPosition, toPosition);
    }

    @Override
    public ItemDraggableRange onGetItemDraggableRange(UserHolder holder, int position) {
        return null;
    }
}
